﻿using Core.Combat.FlyerObj;
using Core.Combat.FlyerObj.Data;
using GCFramework.Utility.ObjectPool;
using Sirenix.OdinInspector;
using UnityEngine;
using UnityEngine.Serialization;

namespace Core.Combat
{
    public class BulletGenerator : MonoBehaviour
    {
        public BulletData bulletData;
        public Bullet bulletPrototype;
        [Title("射击属性")]
        public Transform fireBornPoint;
        
        private float _lastFireTime;

        public void InitData(BulletDataModel dataModel)
        {
            bulletData.InitData(dataModel);
        }

        public void Fire(Vector3 dir)
        {
            if (Time.time > _lastFireTime + (60f / bulletData.fireCoreData.fireRate))
            {
                Generate(dir);
                _lastFireTime = Time.time;
            }
        }

        public void Generate(Vector3 dir)
        {
            // 子弹方向处理区
            BulletFireHandle(ref dir);

            // 子弹创建区
            ScatterBulletHandle(dir);
        }

        /// <summary>
        /// 当子弹被创建出来时
        /// </summary>
        /// <param name="bullet"></param>
        private void OnCreateBullet(Bullet bullet)
        {
            
        }

        private Bullet CreateBullet(Vector3 dir)
        {
            Bullet bullet = PoolManager.Ins.GetFromPool<Bullet>(bulletPrototype);
            OnCreateBullet(bullet);
            bullet.SetGenerator(this);
            bullet.InitBullet(fireBornPoint.position, dir, bulletData);
            return bullet;
        }

        public Bullet CreateBullet(Vector3 pos, Vector3 dir, BulletData data)
        {
            Bullet bullet = PoolManager.Ins.GetFromPool<Bullet>(bulletPrototype);
            bullet.SetGenerator(this);
            bullet.InitBullet(pos, dir, data);
            return bullet;
        }

        #region Fire Core Methods

        /// <summary>
        /// 子弹射击方向偏移
        /// </summary>
        /// <param name="dir">需改变的子弹方向</param>
        private void BulletFireHandle(ref Vector3 dir)
        {
            if (bulletData.fireCoreData.fireDriftAngle == 0)
                return;
            
            dir = Quaternion.AngleAxis(bulletData.fireCoreData.fireDriftAngle, Vector3.forward) * dir;
        }

        private void ScatterBulletHandle(Vector3 dir)
        {
            int totalNum = bulletData.fireCoreData.fireTotalNum;
            if (totalNum > 0)
            {
                for (int i = -totalNum / 2; i <= totalNum / 2; i++)
                {
                    if (totalNum % 2 == 0 && i == 0) continue;

                    float angle = bulletData.fireCoreData.scatterAngle * i;
                    Vector2 scatterDir = Quaternion.AngleAxis(angle, Vector3.forward) * dir;
                    CreateBullet(scatterDir);
                }
            }
        }

        #endregion
        
    }
}